home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Entertainment / tblt / tblt⁄file.c < prev    next >
Encoding:
Text File  |  1986-09-06  |  5.0 KB  |  190 lines  |  [TEXT/MACA]

  1. /*
  2.  * file.c - file handling for the game of Tablut.
  3.  */
  4.  
  5. #include <quickdraw.h>
  6. #include <window.h>
  7. #include <dialog.h>
  8. #include <toolutil.h>
  9. #include <memory.h>
  10. #include <pb.h>
  11. #include <syserr.h>
  12. #include "progerr.h"
  13. #include "tablut.h"
  14.  
  15. #define ALTSAVECHANGE    400    /* "Save changes..." alert ID        */
  16. #define DONTSAVE    3    /* "don't save changes" item        */
  17. #define FILESTRS    130    /* ID for the File I/O strings        */
  18. #define F_SAVE        1    /* the "save doc as..." prompt        */
  19. #define F_NOTITLE    2    /* the name of an untitled file        */
  20.  
  21. /*
  22.  * newgame() - start a new, untitled game.
  23.  */
  24. newgame()
  25. {
  26.     GetIndString(gamename, FILESTRS, F_NOTITLE);
  27.     SetWTitle(mywindow, gamename);
  28.     needsname = 1;
  29.     drawwindow();    /* ...to make sure the window is up-to-date */
  30.     setpieces(); winner = NOWIN; seekboard(0); writeboard(); ischanged = 0;
  31.     setsetup(0);
  32. }
  33.  
  34. /*
  35.  * maysave() - if necessary, ask if the user wants to save the old game.
  36.  *  If desired, save the old game.
  37.  */
  38. int    /* return TRUE if ok, FALSE if the user cancelled    */
  39. maysave()
  40. {
  41.     short itemhit;
  42.  
  43.     if (!ischanged) return(1);
  44.     ParamText(gamename, (char *) 0, (char *) 0, (char *) 0);
  45.     itemhit = Alert(ALTSAVECHANGE, (ProcPtr) 0);
  46.     ResetAlrtStage();
  47.     if (itemhit == DONTSAVE) return(1);
  48.     if (itemhit != OK) return(0);    /* user cancelled    */
  49.     return(savegame(0));
  50. }
  51.  
  52. /*
  53.  * savegame() - save the current game.
  54.  */
  55. int    /* return TRUE if ok, FALSE if cancelled    */
  56. savegame(saveas)
  57. int saveas;    /* if TRUE, let the user choose a new name    */
  58. {
  59.     char str[80];    /* (pascal) prompt string        */
  60.  
  61.     GetIndString(str, FILESTRS, F_SAVE);
  62.     do {
  63.     if (!FileCreate(needsname || saveas, gamename, &gamevnum,
  64.       MYFILE, MYSIGN, str)) {
  65.         return(0);
  66.     }
  67.     SetWTitle(mywindow, gamename);
  68.     } while ((needsname = !writegamefile()));
  69.     return(1);
  70. }
  71.  
  72. /*
  73.  * opengame() - open a previously-saved game.
  74.  */
  75. int    /* return TRUE if ok, FALSE if cancelled    */
  76. opengame()
  77. {
  78.     do {
  79.     if (!FileFetch(gamename, &gamevnum, MYFILE)) return(0);
  80.     SetWTitle(mywindow, gamename);
  81.     } while ((needsname = !readgamefile()));
  82. }
  83.  
  84. /*
  85.  * writegamefile() - write the game out to the existing gamefile.
  86.  */
  87. int    /* TRUE = ok, FALSE = aborted.    */
  88. writegamefile()
  89. {
  90.     OSErr err;
  91.     short fd;            /* reference to the open file        */
  92.     struct moveblock *blk;    /* current chunk to write out        */
  93.     long count;            /* # of bytes to write            */
  94.     short moves;        /* # of moves that have been written    */
  95.     long len;            /* # of bytes in the file        */
  96.  
  97.     if ((err = FSOpen(gamename, gamevnum, &fd)) != noErr) {
  98.     diskerr(err); return(0);
  99.     }
  100.     for (moves = 0, blk = &firstblock; moves < nummoves;
  101.       moves += BDPERBLK, blk = blk->nxtblk) {
  102.     count = nummoves - moves;
  103.     if (count > BDPERBLK) count = BDPERBLK;
  104.     count *= BOARDBYTES;
  105.     if ((err = FSWrite(fd, &count, &(blk->bytes[0]))) != noErr) {
  106.         goto clean1;
  107.     }
  108.     }
  109.     if ((err = GetFPos(fd, &len)) != noErr) goto clean1;
  110.     if ((err = SetEOF(fd, len)) != noErr) goto clean1;
  111.     if ((err = FSClose(fd)) != noErr) goto clean2;
  112.     if ((err = FlushVol((char *) 0, gamevnum)) != noErr) {
  113.     diskerr(err); return(0);
  114.     }
  115.     ischanged = 0;
  116.     return(1);
  117.  
  118. clean1:
  119.     (void) FSClose(fd);
  120. clean2:
  121.     (void) FlushVol((char *) 0, gamevnum);
  122.     diskerr(err);
  123.     return(0);
  124. }
  125.  
  126. /*
  127.  * readgamefile() - read the gamefile.
  128.  *   Note: if the reading fails in the middle, readgamefile()
  129.  *  does a newgame() to avoid leaving a corrupt game record.
  130.  */
  131. int    /* TRUE = ok, FALSE = aborted.    */
  132. readgamefile()
  133. {
  134.     OSErr err;
  135.     short fd;            /* reference to the open file        */
  136.     struct moveblock *blk;    /* current chunk to write out        */
  137.     long count;            /* # of bytes to write            */
  138.     short moves;        /* # of moves that have been written    */
  139.     long total;            /* # of moves in the file        */
  140.     char *malloc();
  141.  
  142.     if ((err = FSOpen(gamename, gamevnum, &fd)) != noErr) {
  143.     diskerr(err); return(0);
  144.     }
  145.     if ((err = GetEOF(fd, &total)) != noErr) {
  146.     diskerr(err); return(0);
  147.     }
  148.     total /= BOARDBYTES;
  149.     if (total < 1) {    /* the file is corrupted    */
  150.     progstop(PE_CORRUPT);
  151.     return(0);
  152.     }
  153.     /* the point of no return.  The next line wrecks the old game */
  154.     nummoves = total; ischanged = 0;
  155.     for (moves = 0, blk = &firstblock; moves < nummoves;
  156.       moves += BDPERBLK, blk = blk->nxtblk) {
  157.     count = nummoves - moves;
  158.     if (count > BDPERBLK) count = BDPERBLK;
  159.     count *= BOARDBYTES;
  160.     if ((err = FSRead(fd, &count, &(blk->bytes[0]))) != noErr) {
  161.         goto clean1;
  162.     }
  163.     if (moves + BDPERBLK < nummoves) {
  164.         if (!blk->nxtblk) {
  165.         if (!(blk->nxtblk = (struct moveblock *)
  166.           malloc(sizeof(struct moveblock)))) {
  167.             err = memFullErr;
  168.             goto clean1;
  169.         }
  170.         blk->nxtblk->nxtblk = (struct movevblock *) 0;
  171.         }
  172.     }
  173.     }
  174.     (void) FSClose(fd);
  175.     (void) FlushVol((char *) 0, gamevnum);
  176.  
  177.     drawwindow();    /* ...to make sure the screen is up-to-date */
  178.     seekboard(nummoves - 1);
  179.     readboard();
  180.     setsetup(0);
  181.     return(1);
  182.  
  183. clean1:
  184.     (void) FSClose(fd);
  185.     (void) FlushVol((char *) 0, gamevnum);
  186.     diskerr(err);
  187.     newgame();        /* ...to clean up the botched game record  */
  188.     return(0);
  189. }
  190.